package com.alibaba.citrus.cr.common.config;

import com.alibaba.lattice2.epoch.tenant.DefaultTenant;
import com.alibaba.ttl.TtlRunnable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.validation.constraints.NotNull;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author: qiaojiange
 * @create: 2021/09/16
 * @Description 线程池配置
 */
@Configuration
public class TreadPoolTaskConfig {
    @Bean("forecastSaleTaskExecutor")
    public ThreadPoolTaskExecutor forecastSaleTaskExecutor() {
        ThreadPoolTaskExecutor forecastSaleTaskExecutor = new ThreadPoolTaskExecutor();
        forecastSaleTaskExecutor.setCorePoolSize(10);
        forecastSaleTaskExecutor.setMaxPoolSize(10);
        forecastSaleTaskExecutor.setQueueCapacity(1000);
        forecastSaleTaskExecutor.setKeepAliveSeconds(60);
        forecastSaleTaskExecutor.setThreadNamePrefix("forecaseSaleTask--");
        forecastSaleTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        forecastSaleTaskExecutor.setAwaitTerminationSeconds(60);
        forecastSaleTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        forecastSaleTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        forecastSaleTaskExecutor.initialize();
        return forecastSaleTaskExecutor;
    }

    @Bean("scItemsQueryTaskExecutor")
    public ThreadPoolTaskExecutor scItemsQueryTaskExecutor() {
        ThreadPoolTaskExecutor forecastSaleTaskExecutor = new ThreadPoolTaskExecutor();
        forecastSaleTaskExecutor.setCorePoolSize(10);
        forecastSaleTaskExecutor.setMaxPoolSize(10);
        forecastSaleTaskExecutor.setQueueCapacity(1000);
        forecastSaleTaskExecutor.setKeepAliveSeconds(60);
        forecastSaleTaskExecutor.setThreadNamePrefix("scItemsQueryTaskTask--");
        forecastSaleTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        forecastSaleTaskExecutor.setAwaitTerminationSeconds(60);
        forecastSaleTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        forecastSaleTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        forecastSaleTaskExecutor.initialize();
        return forecastSaleTaskExecutor;
    }
    @Bean("logsCheckSyncTaskExecutor")
    public ThreadPoolTaskExecutor logsCheckSyncTaskExecutor() {
        ThreadPoolTaskExecutor forecastSaleTaskExecutor = new ThreadPoolTaskExecutor();
        forecastSaleTaskExecutor.setCorePoolSize(10);
        forecastSaleTaskExecutor.setMaxPoolSize(10);
        forecastSaleTaskExecutor.setQueueCapacity(1000);
        forecastSaleTaskExecutor.setKeepAliveSeconds(60);
        forecastSaleTaskExecutor.setThreadNamePrefix("logsCheckSyncTaskExecutor--");
        forecastSaleTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        forecastSaleTaskExecutor.setAwaitTerminationSeconds(60);
        forecastSaleTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        forecastSaleTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        forecastSaleTaskExecutor.initialize();
        return forecastSaleTaskExecutor;
    }
//// 客户同步线程池配置
//    @Bean("customerSyncTaskExecutor")
//    public ThreadPoolTaskExecutor customerSyncTaskExecutor() {
//        ThreadPoolTaskExecutor customerSyncTaskExecutor = new ThreadPoolTaskExecutor();
//        customerSyncTaskExecutor.setCorePoolSize(10);
//        customerSyncTaskExecutor.setMaxPoolSize(10);
//        customerSyncTaskExecutor.setQueueCapacity(1000);
//        customerSyncTaskExecutor.setKeepAliveSeconds(60);
//        customerSyncTaskExecutor.setThreadNamePrefix("customerSyncTask--");
//        customerSyncTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
//        customerSyncTaskExecutor.setAwaitTerminationSeconds(60);
//        customerSyncTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//        // 使用 TtlRunnable
//        customerSyncTaskExecutor.setTaskDecorator(this::decorateTenantCode);
//        customerSyncTaskExecutor.initialize();
//        return customerSyncTaskExecutor;
//    }

    @Bean("salesPlanTaskExecutor")
    public ThreadPoolTaskExecutor salesPlanTaskExecutor() {
        ThreadPoolTaskExecutor salesPlanTaskExecutor = new ThreadPoolTaskExecutor();
        salesPlanTaskExecutor.setCorePoolSize(12);
        salesPlanTaskExecutor.setMaxPoolSize(30);
        salesPlanTaskExecutor.setQueueCapacity(1000);
        salesPlanTaskExecutor.setKeepAliveSeconds(60*10);
        salesPlanTaskExecutor.setThreadNamePrefix("salesPlanTaskExecutor--");
        salesPlanTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        salesPlanTaskExecutor.setAwaitTerminationSeconds(60);
        salesPlanTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        salesPlanTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        salesPlanTaskExecutor.initialize();
        return salesPlanTaskExecutor;
    }

    //报表库存同步线程池配置
    @Bean("inventorySyncTaskExecutor")
    public ThreadPoolTaskExecutor inventorySyncTaskExecutor() {
        ThreadPoolTaskExecutor customerSyncTaskExecutor = new ThreadPoolTaskExecutor();
        customerSyncTaskExecutor.setCorePoolSize(10);
        customerSyncTaskExecutor.setMaxPoolSize(10);
        customerSyncTaskExecutor.setQueueCapacity(1000);
        customerSyncTaskExecutor.setKeepAliveSeconds(60);
        customerSyncTaskExecutor.setThreadNamePrefix("customerSyncTask--");
        customerSyncTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        customerSyncTaskExecutor.setAwaitTerminationSeconds(60);
        customerSyncTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        customerSyncTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        customerSyncTaskExecutor.initialize();
        return customerSyncTaskExecutor;
    }

    //报表月度销售统计线程池配置
    @Bean("monthSalesReportTaskExecutor")
    public ThreadPoolTaskExecutor monthSalesReportTaskExecutor() {
        ThreadPoolTaskExecutor monthSalesReportTaskExecutor = new ThreadPoolTaskExecutor();
        monthSalesReportTaskExecutor.setCorePoolSize(15);
        monthSalesReportTaskExecutor.setMaxPoolSize(50);
        monthSalesReportTaskExecutor.setQueueCapacity(1000);
        monthSalesReportTaskExecutor.setKeepAliveSeconds(60*5);
        monthSalesReportTaskExecutor.setThreadNamePrefix("monthSalesReportTaskExecutor--");
        monthSalesReportTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        monthSalesReportTaskExecutor.setAwaitTerminationSeconds(60);
        monthSalesReportTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        monthSalesReportTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        monthSalesReportTaskExecutor.initialize();
        return monthSalesReportTaskExecutor;
    }


    @Bean("contractStatTaskExecutor")
    public ThreadPoolTaskExecutor contractStatTaskExecutor() {
        ThreadPoolTaskExecutor forecastSaleTaskExecutor = new ThreadPoolTaskExecutor();
        forecastSaleTaskExecutor.setCorePoolSize(10);
        forecastSaleTaskExecutor.setMaxPoolSize(50);
        forecastSaleTaskExecutor.setQueueCapacity(1000);
        forecastSaleTaskExecutor.setKeepAliveSeconds(60);
        forecastSaleTaskExecutor.setThreadNamePrefix("contractStatTaskExecutor--");
        forecastSaleTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        forecastSaleTaskExecutor.setAwaitTerminationSeconds(60);
        forecastSaleTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        forecastSaleTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        forecastSaleTaskExecutor.initialize();
        return forecastSaleTaskExecutor;
    }

    //调拨预报单线程池配置
    @Bean("allocateApplyOrderTaskExecutor")
    public ThreadPoolTaskExecutor allocateApplyOrderTaskExecutor() {
        ThreadPoolTaskExecutor allocateApplyOrderTaskExecutor = new ThreadPoolTaskExecutor();
        allocateApplyOrderTaskExecutor.setCorePoolSize(10);
        allocateApplyOrderTaskExecutor.setMaxPoolSize(10);
        allocateApplyOrderTaskExecutor.setQueueCapacity(1000);
        allocateApplyOrderTaskExecutor.setKeepAliveSeconds(60);
        allocateApplyOrderTaskExecutor.setThreadNamePrefix("allocateApplyOrderTaskExecutor--");
        allocateApplyOrderTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        allocateApplyOrderTaskExecutor.setAwaitTerminationSeconds(60);
        allocateApplyOrderTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        allocateApplyOrderTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        allocateApplyOrderTaskExecutor.initialize();
        return allocateApplyOrderTaskExecutor;
    }


    //调拨预报单线程池配置
    @Bean("allocateApplyTaskExecutor")
    public ThreadPoolTaskExecutor allocateApplyTaskExecutor() {
        ThreadPoolTaskExecutor allocateApplyTaskExecutor = new ThreadPoolTaskExecutor();
        allocateApplyTaskExecutor.setCorePoolSize(10);
        allocateApplyTaskExecutor.setMaxPoolSize(10);
        allocateApplyTaskExecutor.setQueueCapacity(1000);
        allocateApplyTaskExecutor.setKeepAliveSeconds(60);
        allocateApplyTaskExecutor.setThreadNamePrefix("allocateApplyTaskExecutor--");
        allocateApplyTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        allocateApplyTaskExecutor.setAwaitTerminationSeconds(60);
        allocateApplyTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        allocateApplyTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        allocateApplyTaskExecutor.initialize();
        return allocateApplyTaskExecutor;
    }

    //牛要客数据同步任务线程池配置
    @Bean("nykSynTaskExecutor")
    public ThreadPoolTaskExecutor nykSynTaskExecutor() {
        ThreadPoolTaskExecutor nykSynTaskExecutor = new ThreadPoolTaskExecutor();
        nykSynTaskExecutor.setCorePoolSize(10);
        nykSynTaskExecutor.setMaxPoolSize(10);
        nykSynTaskExecutor.setQueueCapacity(10000);
        nykSynTaskExecutor.setKeepAliveSeconds(60);
        nykSynTaskExecutor.setThreadNamePrefix("nykSynTaskExecutor--");
        nykSynTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        nykSynTaskExecutor.setAwaitTerminationSeconds(60);
        nykSynTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        nykSynTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        nykSynTaskExecutor.initialize();
        return nykSynTaskExecutor;
    }

    //牛要客数据同步任务线程池配置
    @Bean("eventTaskExecutor")
    public ThreadPoolTaskExecutor SimpleAsyncTaskExecutor() {
        ThreadPoolTaskExecutor nykSynTaskExecutor = new ThreadPoolTaskExecutor();
        nykSynTaskExecutor.setCorePoolSize(15);
        nykSynTaskExecutor.setMaxPoolSize(50);
        nykSynTaskExecutor.setQueueCapacity(10000);
        nykSynTaskExecutor.setKeepAliveSeconds(60);
        nykSynTaskExecutor.setThreadNamePrefix("eventTaskExecutor");
        nykSynTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        nykSynTaskExecutor.setAwaitTerminationSeconds(60);
        nykSynTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        nykSynTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        nykSynTaskExecutor.initialize();
        return nykSynTaskExecutor;
    }

    @Bean("autoFulfillmentTaskExecutor")
    public ThreadPoolTaskExecutor autoFulfillmentTaskExecutor() {
        ThreadPoolTaskExecutor autoFulfillmentTaskExecutor = new ThreadPoolTaskExecutor();
        autoFulfillmentTaskExecutor.setCorePoolSize(10);
        autoFulfillmentTaskExecutor.setMaxPoolSize(10);
        autoFulfillmentTaskExecutor.setQueueCapacity(5000);
        autoFulfillmentTaskExecutor.setKeepAliveSeconds(60);
        autoFulfillmentTaskExecutor.setThreadNamePrefix("autoFulfillmentTask--");
        autoFulfillmentTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        autoFulfillmentTaskExecutor.setAwaitTerminationSeconds(60);
        autoFulfillmentTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        // 使用 TtlRunnable
        autoFulfillmentTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        autoFulfillmentTaskExecutor.initialize();
        return autoFulfillmentTaskExecutor;
    }

    @Bean("activityTaskExecutor")
    public ThreadPoolTaskExecutor activityTaskExecutor() {
        ThreadPoolTaskExecutor activityTaskExecutor = new ThreadPoolTaskExecutor();
        activityTaskExecutor.setCorePoolSize(10);
        activityTaskExecutor.setMaxPoolSize(10);
        activityTaskExecutor.setQueueCapacity(1000);
        activityTaskExecutor.setKeepAliveSeconds(60);
        activityTaskExecutor.setThreadNamePrefix("activityTask--");
        activityTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        activityTaskExecutor.setAwaitTerminationSeconds(60);
        activityTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 使用 TtlRunnable
        activityTaskExecutor.setTaskDecorator(this::decorateTenantCode);
        activityTaskExecutor.initialize();
        return activityTaskExecutor;
    }

    /**
     * 多租户开发场景下异步线程池中调用需要包装租户code
     * @param runnable
     * @return
     */
    private @NotNull Runnable decorateTenantCode(Runnable runnable) {
        String tenantCode = DefaultTenant.get();
        return TtlRunnable.get(() -> DefaultTenant.runInScope(tenantCode, runnable));
    }
}
